<template>
  <div v-if="isShow" class="image-preview" style="z-index: 3000">
    <div v-if="ops.modal" class="image-preview__mask" @click="close"></div>
    <span class="el-image-viewer__btn el-image-viewer__close" @click="close">
      <i class="el-icon-circle-close"></i>
    </span>
    <span v-if="isRrrow" class="el-image-viewer__btn el-image-viewer__prev" @click="handlePrev()">
      <i class="el-icon-arrow-left"></i>
    </span>
    <span v-if="isRrrow" class="el-image-viewer__btn el-image-viewer__next" @click="handleNext()">
      <i class="el-icon-arrow-right"></i>
    </span>
    <div ref="box" class="image-preview__box">
      <el-carousel
        ref="carousel"
        :show-indicators="false"
        :initial-index="index"
        :initial-swipe="index"
        :interval="0"
        arrow="never"
        indicator-position="none"
        :height="height"
        @change="handleChange"
      >
        <el-carousel-item
          v-for="(item, indexs) in datas"
          :key="indexs"
          @click.native.self="ops.closeOnClickModal ? close() : ''"
        >
          <component
            :is="getIsVideo(item)"
            v-if="getIsVideo(item)"
            :id="'avue-image-preview__' + indexs"
            ref="item"
            :src="item.base64 ?? baseUrl + item.path"
            :style="[styleName]"
            controls="controls"
            ondragstart="return false"
            @click="handleClick(item, indexs)"
            @mousedown="move"
          ></component>
          <div
            v-else
            :id="'avue-image-preview__' + indexs"
            class="image-preview__file"
            @click="handleClick(item, indexs, true)"
          >
            <span>
              <i class="el-icon-document"></i>
              <p>{{ item.name }}</p>
            </span>
          </div>
        </el-carousel-item>
      </el-carousel>
    </div>
    <div class="el-image-viewer__btn el-image-viewer__actions">
      <div class="el-image-viewer__actions__inner">
        <i class="el-icon-zoom-out" @click="subScale"></i>
        <i class="el-icon-zoom-in" @click="addScale"></i>
        <i v-show="!fullScreen" class="el-icon-full-screen" @click="fullScreen = true"></i>
        <i v-show="fullScreen" class="el-icon-c-scale-to-original" @click="fullScreen = false"></i>
        <i class="el-icon-refresh-left" @click="rotate = rotate - 90"></i>
        <i class="el-icon-refresh-right" @click="rotate = rotate + 90"></i>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'ImagePreview',
  data() {
    return {
      left: 0,
      top: 0,
      scale: 1,
      datas: [],
      rotate: 0,
      isShow: false,
      index: 0,
      isFile: false,
      typeList: {
        img: /\.(gif|jpg|jpeg|png|webp|GIF|JPG|PNG)/,
        video: /\.(swf|avi|flv|mpg|rm|mov|wav|asf|3gp|mkv|rmvb|ogg|mp4)/
      },
      baseUrl: process.env.VUE_APP_BASE_API,
      height: '100%',
      fullScreen: false
    }
  },
  computed: {
    styleName() {
      return {
        transform: `scale(${this.scale}) rotate(${this.rotate}deg)`,
        maxWidth: !this.fullScreen ? '100%' : 'none',
        maxHeight: !this.fullScreen ? '100%' : 'none'
      }
    },
    isRrrow() {
      return this.imgLen != 1
    },
    imgLen() {
      return this.imgList.length
    },
    imgList() {
      return this.datas.map((ele) => ele.path)
    }
  },
  methods: {
    handlePrev() {
      this.$refs.carousel.prev()
      this.index = this.$refs.carousel.activeIndex
      this.stopItem()
    },
    handleNext() {
      this.$refs.carousel.next()
      this.index = this.$refs.carousel.activeIndex
      this.stopItem()
    },
    stopItem() {
      this.left = 0
      this.top = 0
      this.$refs.item.forEach((ele) => {
        ele.pause && ele.pause()
      })
    },
    isMedia(item) {
      return this.typeList.img.test(item.path) || this.typeList.video.test(item.path)
    },
    getIsVideo(item) {
      let url = item.path
      let type = item.type
      if (this.typeList.video.test(url) || type == 'video') {
        return 'video'
      } else if (this.typeList.img.test(url) || type == 'img') {
        return 'img'
      }
      return
    },
    subScale() {
      if (this.scale != 0.2) {
        this.scale = parseFloat((this.scale - 0.2).toFixed(2))
      }
    },
    addScale() {
      this.scale = parseFloat((this.scale + 0.2).toFixed(2))
    },
    handleChange() {
      this.scale = 1
      this.rotate = 0
    },
    move(e) {
      // 获取目标元素s
      // 算出鼠标相对元素的位置
      let disX = e.clientX
      let disY = e.clientY
      let scale = 2
      document.onmousemove = (e) => {
        // 鼠标按下并移动的事件
        // 用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
        let left = e.clientX - disX
        let top = e.clientY - disY
        disX = e.clientX
        disY = e.clientY
        // 移动当前元素
        this.left = this.left + left * scale
        this.top = this.top + top * scale
      }
      document.onmouseup = (e) => {
        document.onmousemove = null
        document.onmouseup = null
      }
    },
    handleClick(item, index, df = false) {
      if (typeof this.ops.click == 'function') {
        this.ops.click(item, index)
      } else if (df) {
        window.open(item.path)
      }
    },
    close() {
      this.isShow = false
      if (typeof this.ops.beforeClose == 'function') {
        this.ops.beforeClose(this.datas, this.index)
      }
      this.$destroy()
      this.$el.remove()
    }
  }
}
</script>
<style lang="less" scoped>
.image-preview {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transition: all 0.5s;
  z-index: 9998;
}
.image-preview__mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
}
.image-preview__box {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.image-preview__file {
  text-align: center;
}
.image-preview__box .el-carousel__container {
  height: 100%;
}
.image-preview__box .el-carousel {
  width: 90%;
  height: 100%;
  text-align: center;
}
.image-preview__box .el-carousel__item {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.el-image-viewer__btn {
  z-index: 3000;
}
</style>
